; iotest.asm
				.ORIG	x3000
                LDA     $SP, STACK
                LDA     $IP-0, PROMPT1
                LDA     $R8, OUTSTRING
                JSR     $R8
                
                LDA     $IP-1, NAME
                LDA     $R8, INCHAR
NAME_LOOP       JSR     $R8             ; R0 <- char
                LDI     $R5, x0A        ; x0A = new line character. Sentinel.
                SUB     $R5, $R0
                BRz     NAME_DONE       ; If char was sentinel, done.
                STB     $R0&            ; Else store char to memory.
                BR      NAME_LOOP
                
NAME_DONE       LDA     $IP-0, PROMPT2
                LDA     $R8, OUTSTRING
                JSR     $R8
                
                LDA     $R8, INCHAR
                JSR     $R8
                LDA     $R5, ASCII_Y
                LDW     $R5, $R5
                SUB     $R5, $R0
                BRz     PRINT_NAME
                BR      END
                
PRINT_NAME      LDA     $IP-0, NAME
                LDA     $R8, OUTSTRING
                JSR     $R8
                
END             HALT
PROMPT1         .STRINGZ    "Enter your first name: "
PROMPT2         .STRINGZ    "Print your name (Y/N)? "
ASCII_Y         .DW     0x0059
NAME            .RW     0x10

; Get character from keyboard data0 register, and put character into R0 (LOB).
; Destructive to R0, R1.
INCHAR          LDI     $R1, #1         ; Mask for KBD status signal
IN_LOOP         IN      $R0, x38        ; KBD status -> R0 (LOB)
                AND     $R0, $R1        ; Mask
                BRz     IN_LOOP         ; If no character typed, poll again
                IN      $R0, x3A        ; Character -> R0 (LOB)
                RET

; Take character from R0 (LOB) and put into VID data register.
; Destructive to R1, R2.
OUTCHAR         LDI     $R2, #1         ; Mask for VID status signal
OUT_LOOP        IN      $R1, x30        ; VID status -> R1 (LOB)    
                AND     $R1, $R2        ; Mask
                BRz     OUT_DONE        ; If status[0] = 0, then done.
                BR      OUT_LOOP        ; If status[0] = 1, then poll again.
OUT_DONE        OUT     $R0, x32        ; Else output R0 to VID data register.
                RET

; Outputs a string whose starting address is in IP-0. String format is two
; characters per word. The string must be terminated with a null byte.
; Destructive to R0, R1, R2, IP-0.
OUTSTRING       SUB     $R0, $R0        ; Clear R0.
OUTSTRING_LOOP  LDB     $R0&            ; R0 <- char. IP-0 increments.
                AND     $R0, $R0        ; Set condition codes.
                BRz     OUTSTRING_END   ; Done if at null byte.
                LDA     $R8, OUTCHAR
                JSR     $R8
                BR      OUTSTRING_LOOP
OUTSTRING_END   RET

STACK           .DW     x4000
                .END